package com.lingjtx.auth.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.lingjtx.auth.dao.TobUserAuthorizationMapper;
import com.lingjtx.auth.dao.TobUserInfoMapper;
import com.lingjtx.auth.entity.TobUserAuthorization;
import com.lingjtx.auth.entity.TobUserInfo;
import com.lingjtx.auth.po.UpdatePswPo;
import com.lingjtx.auth.service.UserHandleService;
import com.lingjtx.common.core.algorithm.MD5Util;
import com.lingjtx.common.core.constant.Const;
import com.lingjtx.common.core.token.UserVo;
import com.lingjtx.common.core.util.LinkGenerator;
import com.lingjtx.common.core.util.StringUtil;
import com.lingjtx.common.other.helper.MessageManager;
import com.lingjtx.common.redis.service.IRedisService;
import com.lingjtx.common.security.interceptor.UserContext;
import com.lingjtx.common.security.model.LoginPo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Objects;

@Service
public class TobUserServiceImpl implements UserHandleService<TobUserInfo> {

    private final IRedisService redisService;
    private final TobUserInfoMapper userInfoMapper;
    private final TobUserAuthorizationMapper userAuthorizationMapper;

    public TobUserServiceImpl(IRedisService redisService, TobUserInfoMapper userInfoMapper, TobUserAuthorizationMapper userAuthorizationMapper) {
        this.redisService = redisService;
        this.userInfoMapper = userInfoMapper;
        this.userAuthorizationMapper = userAuthorizationMapper;
    }

    @Override
    public String getUserType() {
        return Const.UserType.TOB;
    }

    @Override
    public TobUserInfo getUserInfo() {
        TobUserInfo userInfo = userInfoMapper.selectById(UserContext.getUser().getUserId());
        if (Objects.nonNull(userInfo)) {
            userInfo.setUserPsw(null);
            userInfo.setUpdateTime(null);
            userInfo.setColStatus(null);
        }
        return userInfo;
    }

    @Override
    public boolean updatePassword(UpdatePswPo model) {
        Long userId = UserContext.getUser().getUserId();
        TobUserInfo userInfo = userInfoMapper.selectById(userId);
        if (Objects.nonNull(userInfo)) {
            if (MD5Util.MD5EncodeUtf8(model.getOldPassword()).equals(userInfo.getUserPsw())) {
                TobUserInfo info = new TobUserInfo();
                info.setUserId(userId);
                info.setUserPsw(MD5Util.MD5EncodeUtf8(model.getNewPassword()));
                info.setUpdateTime(new Date());
                userInfoMapper.updateById(info);
                return true;
            }
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateMobile(UpdatePswPo model) {
        // 更新用户手机，授权表如果有此电话，修改userId
        if (MessageManager.INSTANCE.valid(model.getMobile(), model.getSmsCode(), redisService)) {
            UserVo user = UserContext.getUser();
            TobUserInfo updateUser = new TobUserInfo();
            updateUser.setMobile("");
            updateUser.setUpdateTime(new Date());
            userInfoMapper.update(Wrappers.lambdaUpdate(updateUser).eq(TobUserInfo::getMobile, model.getMobile()));
            TobUserInfo info = new TobUserInfo();
            info.setUserId(user.getUserId());
            info.setMobile(model.getMobile());
            info.setUpdateTime(new Date());
            userInfoMapper.updateById(info);
            // 授权表
            TobUserAuthorization auth = userAuthorizationMapper.selectById(model.getMobile());
            if (auth == null) {
                TobUserAuthorization entity = userAuthorizationMapper.selectById(user.getMobile());
                if (Objects.nonNull(entity)) {
                    entity.setIdentifier(model.getMobile());
                    entity.setUserId(user.getUserId());
                    userAuthorizationMapper.updateById(entity);
                } else {
                    auth = new TobUserAuthorization();
                    auth.setIdentifier(model.getMobile());
                    auth.setUserId(user.getUserId());
                    auth.setIdentityType(Const.IdentityType.MOBILE);
                    userAuthorizationMapper.insert(auth);
                }
            } else {
                auth.setUserId(user.getUserId());
                userAuthorizationMapper.updateById(auth);
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean updateUserInfo(TobUserInfo model) {
        model.setUserId(UserContext.getUser().getUserId());
        return userInfoMapper.updateById(model) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteAccount(LoginPo model) {
        if (!MessageManager.INSTANCE.valid(model.getIdentifier(), model.getSmsCode(), redisService)) {
            return false;
        }
        TobUserAuthorization result = userAuthorizationMapper.selectById(model.getIdentifier());
        if (result != null && result.getUserId().equals(UserContext.getUser().getUserId())) {
            // 账号验证通过，注销账号
            TobUserInfo userInfo = new TobUserInfo();
            userInfo.setUserId(result.getUserId());
            userInfo.setColStatus(Const.ColStatus.DELETE);
            userInfo.setUpdateTime(new Date());
            userInfoMapper.updateById(userInfo);
            // 账号授权表删除
            userAuthorizationMapper.delete(Wrappers.<TobUserAuthorization>lambdaQuery()
                    .eq(TobUserAuthorization::getUserId, result.getUserId()));
            return true;
        }
        return false;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void process(String key) {
        UserVo user = (UserVo) LinkGenerator.getData(key, redisService);
        if (Objects.nonNull(user)
                && Objects.nonNull(user.getUserId())
                && StringUtil.isNotEmpty(user.getEmail())) {
            // 把别的账号绑定该邮箱的解绑
            TobUserInfo updateUser = new TobUserInfo();
            updateUser.setEmail("");
            updateUser.setUpdateTime(new Date());
            userInfoMapper.update(Wrappers.lambdaUpdate(updateUser).eq(TobUserInfo::getEmail, user.getEmail()));

            TobUserInfo info = new TobUserInfo();
            info.setUserId(user.getUserId());
            info.setEmail(user.getEmail());
            info.setUpdateTime(new Date());
            userInfoMapper.updateById(info);
            // 授权表
            TobUserAuthorization auth = new TobUserAuthorization();
            auth.setIdentifier(user.getEmail());
            auth.setUserId(user.getUserId());
            auth.setIdentityType(Const.IdentityType.EMAIL);
            userAuthorizationMapper.insertOrUpdate(auth);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void boundWxOpenid(Long userId, String openid) {
        // 把别的账号绑定该邮箱的解绑
        TobUserInfo updateUser = new TobUserInfo();
        updateUser.setWxOpenid("");
        updateUser.setUpdateTime(new Date());
        userInfoMapper.update(Wrappers.lambdaUpdate(updateUser).eq(TobUserInfo::getWxOpenid, openid));

        TobUserInfo info = new TobUserInfo();
        info.setUserId(userId);
        info.setWxOpenid(openid);
        info.setUpdateTime(new Date());
        userInfoMapper.updateById(info);

        TobUserAuthorization auth = new TobUserAuthorization();
        auth.setIdentifier(openid);
        auth.setUserId(userId);
        auth.setIdentityType(Const.IdentityType.WEXIN);
        userAuthorizationMapper.insertOrUpdate(auth);
    }
}
